package org.jeecg.modules.middleware.rabbitmq.gen.handler.impl;

import com.alibaba.fastjson.JSONObject;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.api.wlhy.app.DingWeiModel;
import org.jeecg.modules.api.wlhy.app.InitReturnBean;
import org.jeecg.modules.api.wlhy.app.LocalModel;
import org.jeecg.modules.api.wlhy.app.bean.LocationInfo;
import org.jeecg.modules.api.wlhy.app.bean.ShippingNoteInfo;
import org.jeecg.modules.api.wlhy.app.utils.HttpUtils;
import org.jeecg.modules.middleware.rabbitmq.gen.EnumGenHandler;
import org.jeecg.modules.middleware.rabbitmq.gen.dto.ScopeRequest;
import org.jeecg.modules.middleware.rabbitmq.gen.handler.IGenMqHandle;
import org.jeecg.modules.wlhy.hyconfig.entity.HyConfig;
import org.jeecg.modules.wlhy.hydriver.entity.HyDriver;
import org.jeecg.modules.wlhy.hydriver.service.IHyDriverService;
import org.jeecg.modules.wlhy.hyvehicle.entity.HyVehicle;
import org.jeecg.modules.wlhy.hyvehicle.service.IHyVehicleService;
import org.jeecg.modules.wlhy.lnglat.entity.HyShippingnoteLnglat;
import org.jeecg.modules.wlhy.lnglat.service.IHyShippingnoteLnglatService;
import org.jeecg.modules.wlhy.shipping.entity.HyShippingNote;
import org.jeecg.modules.wlhy.shippingnoteviolation.entity.HyShippingNoteViolation;
import org.jeecg.modules.wlhy.shippingnoteviolation.service.IHyShippingNoteViolationService;
import org.jeecg.modules.wlhy.utils.HyConfigUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;


/**
 * 交通部sdk2.0
 */
@Service
public class DingWeiHandler implements IGenMqHandle {

    private static final Logger LOGGER = LoggerFactory.getLogger(DingWeiHandler.class);

    @Value(value = "${bpt-2.0.url}")
    private String bpturl;

    @Autowired
    private IHyVehicleService hyVehicleService;

    @Autowired
    private IHyShippingNoteViolationService shippingNoteViolationService;

    @Autowired
    private IHyDriverService hyDriverService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private IHyShippingnoteLnglatService hyShippingnoteLnglatService;

    @Override
    public String getHandlerName() {
        return EnumGenHandler.DINGWEI_SDK.getHandlerName();
    }

    @Override
    public void handle(String channel , String msg) {

        HyConfig config = HyConfigUtils.getConfig();
        if(config==null){
            return;
        }

        try {
            DingWeiModel dingWeiModel =  JSONObject.parseObject(msg, DingWeiModel.class);

            int reportPlatformType = dingWeiModel.getReportPlatformType();
            HyShippingNote shippingNote = dingWeiModel.getHyShippingNote();
            if(shippingNote == null){
                return;
            }

            InitReturnBean init = null;
            if(1==reportPlatformType){
                if(!config.getWzHbIzUse()){
                    return;
                }
                init = HyConfigUtils.getInitReturnBean();
            }else if (2==reportPlatformType){
                if(!config.getWzTjIzUse()){
                    return;
                }
                init = HyConfigUtils.getTjinitReturnBean();
            }else if (3==reportPlatformType){
                if(!config.getWzAhIzUse()){
                    return;
                }
                init = HyConfigUtils.getAhinitReturnBean();
            }else if (4==reportPlatformType){
                if(!config.getWzJsIzUse()){
                    return;
                }
                init = HyConfigUtils.getJsinitReturnBean();
            }else if (5==reportPlatformType){
                if(!config.getWzSxIzUse()){
                    return;
                }
                init = HyConfigUtils.getSxinitReturnBean();
            }else if (6==reportPlatformType){
                if(!config.getWzSdIzUse()){
                    return;
                }
                init = HyConfigUtils.getSdinitReturnBean();
            }else if (7==reportPlatformType){
                if(!config.getWzHbIzUse()){
                    return;
                }
                init = HyConfigUtils.getInitReturnBean();
            }else{
                if(!config.getWzHbIzUse()){
                    return;
                }
                init = HyConfigUtils.getInitReturnBean();
            }

            if(init != null){
                if(!init.isResult()){
                    System.out.println("未初始化成功,不能上报位置信息");
                    return;
                }

                String jingdu = dingWeiModel.getJingdu();
                String weidu = dingWeiModel.getWeidu();
                if("0".equals(jingdu)||"0".equals(weidu)){
                    return;
                }
                String type = dingWeiModel.getType();
                int a = Integer.parseInt(type);
                HyVehicle vehicle = hyVehicleService.getById(shippingNote.getVehicleId());
                if(vehicle == null){
                    return;
                }
                HyDriver driver = hyDriverService.getById(shippingNote.getDriverId());
                if(driver==null){
                    return;
                }

                String shippingNoteNumber = shippingNote.getShippingNoteNumber();
                String deviceId = null;
                String rk = "deviceId:" +  shippingNoteNumber;
                if ( !redisUtil.hasKey(rk)){
                    deviceId = UUID.randomUUID().toString().replace("-", "");
                    redisUtil.set(rk,deviceId,3*24*60*60);
                }else {
                    deviceId = (String) redisUtil.get(rk);
                }
                List<ShippingNoteInfo> list = new ArrayList<>();
                ShippingNoteInfo info = new ShippingNoteInfo();
                info.setAlreadySendCount(0);
                info.setSendCount(1);
                info.setSerialNumber("0000");
                info.setShippingNoteNumber(shippingNoteNumber);
                info.setStartCountrySubdivisionCode(shippingNote.getSendAreaCode());
                info.setEndCountrySubdivisionCode(shippingNote.getReceiveAreaCode());

                info.setStartLocationText(shippingNote.getSendAddressName());
                info.setStartLongitude(Double.parseDouble(shippingNote.getSendLongitude().toString()));
                info.setStartLatitude(Double.parseDouble(shippingNote.getSendLatitude().toString()));
                info.setEndLocationText(shippingNote.getReceiveAddressName());
                info.setEndLongitude(Double.parseDouble(shippingNote.getReceiveLongitude().toString()));
                info.setEndLatitude(Double.parseDouble(shippingNote.getReceiveLatitude().toString()));

                list.add(info);
                LocationInfo locationInfo = new LocationInfo();

                locationInfo.setLongitude(Double.parseDouble(jingdu));

                locationInfo.setLatitude(Double.parseDouble(weidu));

                locationInfo.setLocationText("");
                locationInfo.setLocationTime(System.currentTimeMillis());
                locationInfo.setLocationType(a);
                locationInfo.setRemark("");
                locationInfo.setCountrySubdivisionCode("");

                locationInfo.setVehicleNumber(vehicle.getVehicleNumber());
                locationInfo.setDriverName(driver.getDriverName());

                locationInfo.setRandomPublicKey(init.getPublicKey());

                locationInfo.setDeviceId(deviceId);

                locationInfo.setShippingNoteInfos(list);
                List<LocationInfo> locationInfos = new ArrayList<>();
                locationInfos.add(locationInfo);


                LocalModel localModel =new LocalModel();
                localModel.setLocationInfos(locationInfos);
                localModel.setInitReturnBean(init);

                String localModeStr = JSONObject.toJSONString(localModel);
                String res = HttpUtils.sendPost(bpturl+"uploadLocalhost",localModeStr);
                //0成功 1失败
                HyShippingnoteLnglat shippingnoteLnglat =new HyShippingnoteLnglat();
                if("0".equals(res)) {
                    shippingnoteLnglat.setState("0");
                }else{
                    shippingnoteLnglat.setState("1");
                }

                    shippingnoteLnglat.setType(type);
                    shippingnoteLnglat.setShippingNum(shippingNoteNumber);
                    shippingnoteLnglat.setLongitude(Double.parseDouble(jingdu));
                    shippingnoteLnglat.setLatitude(Double.parseDouble(weidu));
                    shippingnoteLnglat.setCreateTime(new Date());
                    hyShippingnoteLnglatService.save(shippingnoteLnglat);
//                ResBaseBean resBaseBean = AppUtils.initUploadLocation(locationInfos, init);
                //结束位置上传

                this.savaShippingNoteViolation( shippingNote , type ,Double.parseDouble(jingdu) ,Double.parseDouble(weidu));
            }
        } catch (Exception e) {
            LOGGER.error("发送位置信息失败:{}", e.getMessage());
        }

    }

    /**
     * 记录司机违规行为
     * @param shippingNote
     * @param type
     * @param jingdu
     * @param weidu
     */
    private  void  savaShippingNoteViolation(HyShippingNote shippingNote ,String type ,double jingdu ,double weidu){
        HyShippingNoteViolation shippingNoteViolation = new HyShippingNoteViolation();
        shippingNoteViolation.setShippingNoteId(shippingNote.getId());
        shippingNoteViolation.setShippingNoteNumber(shippingNote.getShippingNoteNumber());
        shippingNoteViolation.setDriverId(shippingNote.getDriverId());
        shippingNoteViolation.setVehicleId(shippingNote.getVehicleId());
        shippingNoteViolation.setViolationTime(new Date());
        ScopeRequest scopeRequest = new ScopeRequest(jingdu, weidu);
        if("0".equals(type)) {
            String sendLongitude = shippingNote.getSendLongitude().toString();
            String sendLatitude = shippingNote.getSendLatitude().toString();
            boolean inPolygon = getPunch(scopeRequest, sendLongitude, sendLatitude);
            if (!inPolygon) {
                shippingNoteViolation.setViolationType("2");
                shippingNoteViolationService.save(shippingNoteViolation);
            }
        }
        if("1".equals(type)){
            String receiveLongitude =   shippingNote.getReceiveLongitude().toString() ;
            String receiveLatitude =    shippingNote.getReceiveLatitude().toString() ;
            boolean inPolygon = getPunch( scopeRequest , receiveLongitude , receiveLatitude);
            if(!inPolygon ){
                shippingNoteViolation.setViolationType("3");
                shippingNoteViolationService.save(shippingNoteViolation)  ;
            }
        }



    }

    public static void main(String[] args) {
        String longitude = "116.489653";
        String latitude = "39.918166";
        ScopeRequest scopeRequest = new ScopeRequest(116.559660 , 39.918100);
        boolean a = getPunch( scopeRequest , longitude , latitude);
        System.out.println(a);
    }

    /**
     *
     * @param platPunch 用户所在位置
     * @param longitudeS 设置目的地经度
     * @param latitudeS  设置目的纬度
     * @return
     */
    private static  boolean getPunch(ScopeRequest platPunch ,String longitudeS ,String latitudeS){
//        //1、设置目的地经度
//        String longitudeS = “106.235321”
//        //设置目的纬度
//        String latitudeS = “37.432579”;
        // 2、由前端传过来的用户所在位置 经纬度
        String longitudeT = platPunch.getLongitude().toString();
        String latitudeT = platPunch.getLatitude().toString();
        // 3、对比
        GlobalCoordinates source = new GlobalCoordinates(Double.parseDouble(latitudeS), Double.parseDouble(longitudeS));
        GlobalCoordinates target = new GlobalCoordinates(Double.parseDouble(latitudeT), Double.parseDouble(longitudeT));
        //这是两种坐标系计算方法，这是第一种坐标系计算方法（我们用的这种）
        double geoCurve = getDistanceMeter(source, target, Ellipsoid.Sphere);
        //这是两种坐标系计算方法，这是第二种坐标系计算方法
        double geoCurve2 = getDistanceMeter(source, target, Ellipsoid.WGS84);
        System.out.println(geoCurve + "----------" + geoCurve2);
        //如果用户和目的地位置想吃10千米，在不能打卡；
        if (geoCurve > 10000){
            return false;
        } else{
          return true;
        }

    }
    /* 经纬度计算工具类*/
    public static double getDistanceMeter(GlobalCoordinates gpsFrom, GlobalCoordinates gpsTo, Ellipsoid ellipsoid)
    {
        //创建GeodeticCalculator，调用计算方法，传入坐标系、经纬度用于计算距离
        GeodeticCurve geoCurve = new GeodeticCalculator()
                .calculateGeodeticCurve(ellipsoid, gpsFrom, gpsTo);
        return geoCurve.getEllipsoidalDistance();
    }







}

